(* Initialisation de SDL *)
let sdl_init () =
  begin
    Sdl.init [`VIDEO];
    Sdlevent.enable_events Sdlevent.all_events_mask;
  end 

(* Dimensions d'une image *)
let get_dims img =
  ((Sdlvideo.surface_info img).Sdlvideo.w, (Sdlvideo.surface_info
  img).Sdlvideo.h)

let rec existpix x = function
  |[] -> false
  |e::l -> (e = x) || existpix x l

(* Afficher une image*)
let show img dst =
  let d = Sdlvideo.display_format img in
    Sdlvideo.blit_surface d dst ();
    Sdlvideo.flip dst
 
(*renvoie un réel entre 0 et 1 représentant l'intensité lumineuse du                                                                                         
  pixel*)
let level (r,g,b) = (0.3 *. float_of_int(r) +. 0.59 *. float_of_int(g)
		     +. 0.11 *. float_of_int(b))
  /. 255.

(*renvoie triplet gris a partir de level*)
let color2grey (r,g,b) =
  let a = int_of_float((level(r,g,b))*.255.) in (a,a,a)

(*image2grey*)
let image2grey img dst =
  let (w,h)= get_dims(img) in
    for x = 0 to w-1 do
      for y = 0 to h-1 do
	Sdlvideo.put_pixel_color dst x y
	  (color2grey(Sdlvideo.get_pixel_color
                        img x y))
      done
    done

(* Comparaison de pixels *)
let cp_pix img x1 y1 x2 y2 = let gpc = Sdlvideo.get_pixel_color in
			     gpc img x1 y1 = gpc img x2 y2


(*String obj*)
let v_obj (a,b,c)  str  = ((str)^" "^(string_of_int(a))^".0 "^(string_of_int(b))^".0 "^(string_of_int(c))^".0 \n")

(*Dictionnaire Couleur/Valeur*)
let rec dicoSheet key = function
  | [] -> raise Not_found
  | (keyy, vall) :: tab -> if (key = keyy) then vall else dicoSheet key tab



(* créer un vecteur*)
let makeVect vect p1 p2 = 
 !vect.(0) <- p1.(0) - p2.(0);
 !vect.(1) <- p1.(1) - p2.(1);
 !vect.(2) <- p1.(2) - p2.(2);
 !vect 

  
(*Calcul la norme*)
let makeNorm norm vecteur1 vecteur2 = 
 let (x,y,z) = (0,1,2) in
 !norm.(x) <- vecteur1.(y) * vecteur2.(z) - vecteur1.(z) * vecteur2.(y);
 !norm.(y) <- vecteur1.(z) * vecteur2.(x) - vecteur1.(x) * vecteur2.(z);
 !norm.(z) <- vecteur1.(x) * vecteur2.(y) - vecteur1.(y) * vecteur2.(x);
 !norm

let tripToTab (a,b,c) = 
   let tab =Array.make 3 0 in
   tab.(0) <- a;
   tab.(1) <- b;
   tab.(2) <- c;
   tab

let tabToTrip tab = 
   let x = tab.(0) in
   let y = tab.(1) in
   let z = tab.(2) in
   (x,y,z)
	
let normal p1 p2 p3 =
 let norm = ref (Array.make 3 0) in
 let vecteur1 = makeVect (ref (Array.make 3 0)) p1 p2 in
 let vecteur2 = makeVect (ref (Array.make 3 0)) p2 p3 in
   makeNorm norm vecteur1 vecteur2




let objMake img pas color =
  let relief = open_out "relief.obj" in
  let (w,h) = get_dims img in
  let xP = w/pas in
  let yP = h/pas in
  let tab = ref(Array.make_matrix (xP+1) (yP+1) (15,15,15)) in
  let nb =ref 1 in
  let listeColor = function
	| 0 -> 50
	|1->100
        | _ ->150 in 
  let countTMPcolor = ref 0 in
for i = 0 to w-1 do
    for j = 0 to h-1 do
      if (i mod pas = 0 && j mod pas = 0 ) then
	!tab.(i/pas).(j/pas) <- (i,j, listeColor(!countTMPcolor mod 3 ) (*(dicoSheet(Sdlvideo.get_pixel_color img  i j) color)  *) );
    done;
    countTMPcolor := !countTMPcolor + 1;
  done;
 for j=0 to yP-1 do
    for i=0 to xP do 
      output_string relief (v_obj(!tab.(i).(j))  "v" );
      nb := !nb + 1;
     done;
 done;
nb := 0;
output_string relief "\n";
(*Calcul des triangles*)
let wTN = ((xP-1)*2) in
let hTN = ((yP-1)*2) in
let triangle =  Array.make_matrix wTN hTN ((0,0,0),(0,0,0),(0,0,0)) in
let normalTab = Array.make_matrix wTN hTN (0,0,0) in
let indexW = ref 0 in
let indexH = ref 0 in
let str (a,b)= (string_of_int(a))^" "^(string_of_int(b))^" //  " in
let str2 (a,b,c)= (string_of_int(a))^" "^(string_of_int(b))^(string_of_int(c))^" //  " in
let face = ref 1 in
let f f = string_of_int(!f) in
let nbN = ref 1 in
for j=0 to (h/pas) do
 for i=0 to (w/pas) do
    try begin
         let (x1,y1,z1) = !tab.(i).(j) in
	 let (x2,y2,z2) = !tab.(i+1).(j) in
	 let (x3,y3,z3) = !tab.(i+1).(j+1) in
	 let (x4,y4,z4) = !tab.(i).(j+1) in
         triangle.(!indexW).(!indexH) <- ((x1,y1,z1), (x4,y4,z4), (x3,y3,z3)); 
         normalTab.(!indexW).(!indexH) <- tabToTrip(normal (tripToTab(x1,y1,z1)) (tripToTab(x4,y4,z4)) (tripToTab(x3,y3,z3)));
         output_string relief (v_obj  normalTab.(!indexW).(!indexW)  "vn" ); 
         triangle.(!indexW+1).(!indexH) <- ((x1,y1,z1), (x2,y2,z2), (x3,y3,z3));
         normalTab.(!indexW+1).(!indexW) <- tabToTrip(normal (tripToTab(x3,y3,z3)) (tripToTab(x4,y4,z4)) (tripToTab(x1,y1,z1)));
         output_string relief (v_obj  normalTab.(!indexW+1).(!indexW) "vn" );
         nb := !nb+1;
	 indexW := !indexW+2;
  	end      
    with _ -> print_string(str(i,j)^" \n") 
 done;
 indexW := 0;
 indexH := !indexH +1;
 done;
output_string relief "\n";
(*ecriture des faces*)
for j= 0 to ((h/pas)-2) do
 for i= 0 to ((w/pas)-2) do
    try begin
    	 output_string relief ("f "^string_of_int(!face)^"//"^string_of_int(!nbN)^" "^string_of_int(!face+xP+1)^"//"^string_of_int (!nbN)^" "^string_of_int(!face+xP+2)^"//"^string_of_int(!nbN)^"\n");        
    	 output_string relief ("f "^string_of_int(!face)^"//"^string_of_int(!nbN)^" "^string_of_int(!face+1)^"//"^string_of_int (!nbN)^" "^string_of_int(!face+xP+2)^"//"^string_of_int(!nbN)^"\n" );
	 nbN := !nbN + 1;         
         face := !face + 1;
        end
    with _ -> print_string("fail write face")
 done;
done;
 close_out relief


(*delimitation des contours et reperage des couleurs*)
let traitement img dst =
  let (w,h)= get_dims img in
  let fichier = open_out "sauv.txt" in
  let liste = ref [(0,0,0)] in
  for i = 0 to w-1 do
    for j = 0 to h-1 do
      (* reperage des couleurs *)
      let (r,g,b) = Sdlvideo.get_pixel_color img i j in
      if (existpix (r,g,b) !liste) then ()
      else begin
	liste := (r,g,b)::!liste;
	output_string fichier (string_of_int((r))^" "^(string_of_int(g))^"  "^(string_of_int(b))^" \n")
      end;
      (* délimitation des contours *)
      if ( not (cp_pix img i j (i+1) j) || not (cp_pix img i j i (j+1)) )
      then
	Sdlvideo.put_pixel_color dst i j (0,0,0)
      else
	Sdlvideo.put_pixel_color dst i j (Sdlvideo.get_pixel_color img i j)	  
    done;
  done;
  close_out fichier


let quadrille src dst accuracy = 
    let (w,h)= get_dims src in
      for x=0 to (w-1) do
	  for y=0 to (h-1) do
	    let yppc = (h/accuracy) in
	    let xppc = (w/accuracy) in
	    if (y mod yppc == 0)then
	      Sdlvideo.put_pixel_color dst x y (0,0,0)
	    else
	      if (x mod xppc == 0) then
		Sdlvideo.put_pixel_color dst x y (0,0,0)
	      else
		if (x mod xppc == y mod yppc) then
		  Sdlvideo.put_pixel_color dst x y (0,0,0)
		else
		  Sdlvideo.put_pixel_color dst x y
		    (Sdlvideo.get_pixel_color src x y)
	  done;
      done	 

let savepixelcolor img =
  let (w,h)= get_dims img in
  let fichier = open_out "sauv.txt" in
  let liste = ref [(0,0,0)] in
  for i = 0 to w-1 do
    for j = 0 to h-1 do
      let (r,g,b) = Sdlvideo.get_pixel_color img i j in
      if (existpix (r,g,b) !liste) then ()
      else begin
	liste := (r,g,b)::!liste;
	output_string fichier (string_of_int((r))^" "^(string_of_int(g))^"  "^(string_of_int(b))^" \n")
      end
    done;
  done;
  close_out fichier  


let rec insert e = function 
  |[] -> [e]
  |x::l -> if e < x then e::x::l else x::insert e l
 
let rec tri = function
  |[] -> []
  |t::l -> insert t (tri l)

let median_filter src dst =
  let (w,h) = get_dims src in
  for x = 1 to w-1 do
    for y = 1 to h-1 do 
      let liste = ref [] in liste:=[(Sdlvideo.get_pixel_color src (x-1) (y-1));
				    (Sdlvideo.get_pixel_color src (x-1) (y));
				   (Sdlvideo.get_pixel_color src (x-1) (y+1));
				   (Sdlvideo.get_pixel_color src x (y-1));
				   (Sdlvideo.get_pixel_color src x y);
				   (Sdlvideo.get_pixel_color src x (y+1));
				   (Sdlvideo.get_pixel_color src (x+1) (y-1));
				   (Sdlvideo.get_pixel_color src (x+1) y);
				   (Sdlvideo.get_pixel_color src (x+1) (y+1))];
Sdlvideo.put_pixel_color dst x y (List.nth (tri (!liste)) ((List.length (tri (!liste)))/2));
    done
  done



